#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

#include "mystdio.h"


const char* toString(int flag)
{
    if(flag & NONE_FLUSH) return "NONE";
    else if(flag & LINE_FLUSH) return "line";
    else if(flag & FULL_FLUSH) return "full";
    else return "Unknow";
}

void DebugPrint(myfile* fp)
{
    printf("ouytbuffer: %s\n",fp->outbuffer);
    printf("fd: %d\n",fp->fileno);
    printf("pos: %d\n",fp->pos);
    printf("cap: %d\n",fp->cap);
    printf("flush_mode: %s\n",toString(fp->flush_mode));
}

myfile* myfopen(const char* pathname, const char* mode)
{
    int flag = 0;
    if(strcmp("r",mode) == 0)
    {
        flag |= (O_RDONLY); 
    }
    else if(strcmp("w",mode) == 0)
    {
        flag |= (O_WRONLY | O_CREAT | O_TRUNC);
    }
    else if(strcmp("a",mode) == 0)
    {
        flag |= (O_WRONLY | O_CREAT | O_APPEND);
    }
    else return NULL;
    
    int fd = 0;
    if(flag & O_WRONLY)
    {
        umask(0);
        fd = open(pathname,flag,0666);
    }
    else fd = open(pathname,flag);

    if(fd < 0) return NULL;
   
    myfile* fp = (myfile*)malloc(sizeof(myfile));
    if(fp == NULL) return NULL;
    fp->fileno = fd;
    fp->cap = SIZE;
    fp->pos = 0;
    fp->flush_mode = LINE_FLUSH;

    return fp;

}


void my_flush(myfile* fp)
{
    if(fp->pos == 0) return;
    write(fp->fileno,fp->outbuffer,fp->pos);
    fp->pos = 0;
}

int my_fwrite(myfile* fp,const char* s,int size)
{
    memcpy(fp->outbuffer + fp->pos,s,size);
    fp->pos += size;

    //判断是否要刷新
    if((fp->flush_mode & LINE_FLUSH) && (fp->outbuffer[fp->pos-1] == '\n'))
    {
        my_flush(fp);
    }
    else if((fp->flush_mode & FULL_FLUSH) & (fp->pos == fp->cap))
    {
        my_flush(fp);
    }
    return size;
    
}

void my_fclose(myfile* fp)
{
    my_flush(fp);
    close(fp->fileno);
    free(fp);
}


